package chpt09.testsync;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SyncCounterWithLock {
	private static int value = 0;
	private static Lock lock = new ReentrantLock();
	
	public static void inc() {
		lock.lock();
		try {
			int x = getValue();
			x++;
			value = x;
		} finally {
			lock.unlock();
		}
	}

	public static void dec() {
		lock.lock();
		try {
			int x = getValue(); 
			x--;
			value = x;
		} finally {
			lock.unlock();
		}
		
	}

	public static int getValue() {
		return value;
	}
	public static void main(String[] args) throws InterruptedException {
		int n = 10000; // 执行次数
		Thread t1 = new Thread(new AdderTestLock(n));
		Thread t2 = new Thread(new AdderTestLock(n));
		Thread t3 = new Thread(new AdderTestLock(n));

		Thread t4 = new Thread(new SubtracterTestLock(n));
		Thread t5 = new Thread(new SubtracterTestLock(n));
		Thread t6 = new Thread(new SubtracterTestLock(n));

		t1.start();t2.start();t3.start();
		t4.start();t5.start();t6.start();
		t1.join();t2.join();t3.join();
		t4.join();t5.join();t6.join();

		System.out.println("SyncCounterWithLock.getValue="+
				SyncCounterWithLock.getValue());
		System.out.println("main end");
	}
}

class AdderTestLock implements Runnable{
	private int n; // 执行次数
	public AdderTestLock(int n) {
		this.n = n;
	}

	@Override
	public void run() {
		for (int i = 0; i < n; i++)
			SyncCounterWithLock.inc();
		String name = Thread.currentThread().getName();
		System.out.printf("%s add %d. End!%n", name, n);
	}
}

class SubtracterTestLock implements Runnable {
	private int n;
	public SubtracterTestLock(int n) {
		this.n = n;
	}

	@Override
	public void run() {
		for (int i = 0; i < n; i++)
			SyncCounterWithLock.dec();
		String name = Thread.currentThread().getName();
		System.out.printf("%s subtract %d. End!%n", name, n);
	}
}